﻿using Cuofrisp.Core.ParallelCore.Tools;
using MathNet.Symbolics;

namespace Cuofrisp.Core.ParallelCore
{
    public partial class ParallelCuofrispCalculator
    {
        private void SetChristoffelAndDerivative(CuofrispResult result)
        {
            _ = Parallel.For(0, result.Christoffel.Length,
                this.parallelOptions,
                (sigmaMuNu) => {
                    var (sigma, mu, nu) = sigmaMuNu.As3dIndex(result.VariableCount);

                    // 克氏符
                    var values = Enumerable.Range(0, result.VariableCount).Select(
                        (rho) => {
                            var factor1 = result.MetricInverse[rho, sigma];
                            var factor2Item1 = result.MetricDerivative[mu, rho, nu];
                            var factor2Item2 = result.MetricDerivative[nu, rho, mu];
                            var factor2Item3 = result.MetricDerivative[mu, nu, rho];
                            var factor2 = factor2Item1 + factor2Item2 - factor2Item3;
                            return factor1 * factor2 / 2;
                        });
                    var gamma = SymbolicExpression.Zero;
                    foreach (var value in values)
                        gamma += value;
                    gamma = this.simplifier.Simplify(gamma);
                    result.Christoffel[sigma, mu, nu] = gamma;

                    // 求导
                    foreach (var alpha in Enumerable.Range(0, result.VariableCount))
                    {
                        result.ChristoffelDerivative[sigma, mu, nu, alpha]
                            = this.simplifier.Simplify(gamma.Differentiate(result.Variables[alpha]));
                    }
                });
        }
    }
}